#ifndef __baker_Vector_h__
#define __baker_Vector_h__

#include "Prerequire.h"

namespace baker
{
    /** Base of the Vector
    */
    template< int N >
    struct VecBase
    {
        /** The data */
        real v[N];

        enum { CNT = N };

        /** Access an item by index
        */
        inline real & operator [] ( guint index )
        {
            g_assert( index < N );
            return v[index];
        }

        inline const real & operator [] ( guint index ) const
        {
            g_assert( index < N );
            return v[index];
        }

    };
    /** A 2d Vector structure
     */
    struct Vec2 : public VecBase<2>
    {
        /** Default constructor, the values will not be initialized.
        */
        Vec2( void );

        /** Constructor will initializing values
        */
        Vec2( real x
            , real y
            );

        /** set x */
        inline Vec2 & x( real f ) { v[0] = f; return *this; }

        /** set y */
        inline Vec2 & y( real f ) { v[1] = f; return *this; }

        /** get x */
        inline real x() const { return v[0]; }

        /** get y */
        inline real y() const { return v[1]; }

    };

    /** A 3d Vector structure
     */
    struct Vec3 : public VecBase<3>
    {
        /** Default constructor, the values will not be initialized.
        */
        Vec3( void );

        /** Constructor will initializing values
        */
        Vec3( real x
            , real y
            , real z
            );

        /** Constructor will initializing values
        */
        Vec3( const Vec2 & xy
            , real z
            );

        /** set x */
        inline Vec3 & x( real f ) { v[0] = f; return *this; }

        /** set y */
        inline Vec3 & y( real f ) { v[1] = f; return *this; }

        /** set z */
        inline Vec3 & z( real f ) { v[2] = f; return *this; }

        /** get x */
        inline real x() const { return v[0]; }

        /** get y */
        inline real y() const { return v[1]; }

        /** get z */
        inline real z() const { return v[2]; }

        /** get the xy value */
        inline Vec2 xy() const { return Vec2( v[0], v[1] ); }
    };
}

#include "VectorOp.h"

#endif  // __baker_Vector_h__
